export {};
/*
访问装饰器
  访问器:get、set
  访问器装饰器会在调用时传入下列3个参数：
    1. 对于静态成员来说是类的构造函数，对于实例成员来说是类的原型对象
    2. 成员的名称
    3. 成员的属性描述符

  注意：
    TypeScript disallows decorating both the get and set accessor for a single member. Instead, all decorators for the member must be applied to the first accessor specified in document order. This is because decorators apply to a Property Descriptor, which combines both the get and set accessor, not each declaration separately.
    不允许同时装饰一个成员的get和set访问器
    一个成员的所有装饰的必须应用在文档顺序的第一个访问器上

    访问器装饰器不能用在声明文件中（.d.ts），或者任何外部上下文（比如 declare的类）里。

*/
function enumerable(bool: boolean) {
  return function(
    target: any,
    propertyName: string,
    descriptor: PropertyDescriptor
  ) {
    descriptor.enumerable = bool;
  };
}
class Info {
  private _name: string;
  constructor(name: string) {
    this._name = name;
  }
  @enumerable(false)
  get name() {
    return this._name;
  }
  // @enumerable(false) // error 不能向多个同名的 get/set 访问器应用修饰器 TS1207: Decorators cannot be applied to multiple get/set accessors of the same name.
  set name(name) {
    this._name = name;
  }
}
/*↑
这里我们同时给 name 属性的 set 和 get 访问器使用了装饰器，所以在给定义在后面的 set 访问器使用装饰器时就会报错。
经过 enumerable 访问器装饰器的处理后，name 属性变为了不可枚举属性。*/
let x = new Info('a')
Object.keys(Info.prototype).forEach(item=>console.log(item)) // nothing to console


/** 同样的，如果访问器装饰器有返回值，这个值会被作为属性的属性描述符。*/
